package inherit;

/*class Dog {
    String name;
    double weight;

    public void eat() {
        System.out.println(name + "在吃东西");
    }

    public void wagTail() {
        System.out.println(name + "在摇尾巴");
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", weight=" + weight +
                '}';
    }
}

class Cat {
    String name;
    double weight;

    public void eat() {
        System.out.println(name + "在吃东西");
    }

    public void catchMouse() {
        System.out.println(name + "在抓老鼠");
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", weight=" + weight +
                '}';
    }
}*/

public class Test {
    //通过观察我们发现上面的Dog类和Cat类有很多重复的属性
    //要是有更多的类像上面一样都具有相同的属性时我们就可以通过继承来简化代码
    //提高代码的复用性(重复使用)
    public static void main(String[] args) {
       /* Dog dog1 = new Dog();
        dog1.name = "旺财";
        dog1.weight = 18;*/

        //System.out.println(dog1);
        //dog1.eat();
        //dog1.wagTail();
        /*
         * Dog{name='旺财', weight=18.0}
         * 旺财在吃东西
         * 旺财在摇尾巴
         */
        //子类拥有了父类的属性和方法

        //当在子类中访问一个成员时 会先在子类本身中找 没找到再去父类中找 要还是没找到就报错了
       /* System.out.println(dog1.cnt);
        dog1.eat();*/
        /*
         * 1           //子类中cnt的值
         * 旺财在摇尾巴  //子类中的eat方法
         * 同时在吃东西
         */

        Cat cat1 = new Cat("加菲猫", 100, false);
        System.out.println(cat1);
        /*
         * Animal 静态代码块
         * Cat 静态代码块      //先父类的静态再子类的静态
         * Animal 实例代码块
         * Animal 参数构造
         * Cat 实例代码块
         * Cat 参数构造       //先父类的实例再子类的实例
         * Cat{name='加菲猫', weight=100.0, cnt=0, cute=false}
         */
        System.out.println("+++++++++++++++++++++++++++++++++++++++++++");
        Dog dog2=new Dog();
        /* //父类不再会执行静态代码块(静态代码块仅会执行一次)
         * Dog 静态代码块
         * Animal 实例代码块
         * Animal 参数构造
         * Dog 实例代码块
         * Dog 无参构造
         */

    }
}

class Animal {
    String name;
    double weight;

    Animal(String name, double weight) {//当父类中有了带参数的构造函数
        this.name = name;
        this.weight = weight;
        System.out.println("Animal 参数构造");
    }

    {
        System.out.println("Animal 实例代码块");
    }

    static {
        System.out.println("Animal 静态代码块");
    }

    int cnt = 0;

    public void eat() {
        System.out.println(name + "在吃东西");
    }
}

//子类(派生类)      父类(基类 超类)
class Dog extends Animal {

    int cnt = 1;//在子类中添加与父类同名的成员变量

    Dog() { //则子类中需要用super() 来初始化父类 但这个操作并不会真的实例化一个父类出来
        super("无名请赋值", 0.0);
        System.out.println("Dog 无参构造");
    }

    Dog(String name, double weight) {
        super(name, weight);
        System.out.println("Dog 参数构造");
    }

    {
        System.out.println("Dog 实例代码块");
    }

    static {
        System.out.println("Dog 静态代码块");
    }

    public void eat() {//在子类中添加与父类同名的成员方法
        wagTail();
        System.out.println("同时在吃东西");
    }

    public void wagTail() {
        System.out.println(name + "在摇尾巴");
    }

    @Override
    public String toString() {//在子类中可以直接访问父类的所有属性和方法(受权限限制的除外)
        return "Dog{" +
                "name='" + name + '\'' +
                ", weight=" + weight +
                '}';
    }
}

class Cat extends Animal {
    boolean cute;

    public void catchMouse() {
        System.out.println(name + "在抓老鼠");
    }

    Cat(String name, double weight, boolean cute) {
        super(name, weight);
        this.cute = cute;
        System.out.println("Cat 参数构造");
    }

    {
        System.out.println("Cat 实例代码块");
    }

    static {
        System.out.println("Cat 静态代码块");
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", weight=" + weight +
                ", cnt=" + cnt +
                ", cute=" + cute +
                '}';
    }
}



